package fr.pioug.gdocs.service;

import java.util.*;

import org.apache.commons.lang.*;

import fr.pioug.gdocs.gui.*;
import fr.pioug.gdocs.object.*;

/**
 * @author a011228
 * @version
 */
public abstract class SyncService extends Observable implements Runnable {

	/**
	 * @return
	 */
	protected SyncService() {

	}

	/**
	 * @param pLocalTree
	 * @param pServerTree
	 * @return
	 */
	public List<GDocsFile> diff(GDocsFile pLocalTree, GDocsFile pServerTree) {
		List<GDocsFile> lDocsFileDiff = new ArrayList<GDocsFile>();
		// Local Directory with files
		if (pLocalTree != null && pLocalTree.getListGDocs() != null) {
			for (GDocsFile lDocsFileLocal : pLocalTree.getListGDocs()) {
				// Clone for Diff Tree
				GDocsFile lDocsFile = new GDocsFile(lDocsFileLocal);
				GDocsFile lDocsFileServer = null;
				if (pServerTree != null && pServerTree.getListGDocs() != null
						&& pServerTree.getListGDocs().contains(lDocsFileLocal)) {
					lDocsFileServer = pServerTree.getListGDocs().get(
							pServerTree.getListGDocs().indexOf(lDocsFileLocal));
					LogService.debug("Already on server - "
							+ lDocsFileServer.getName(), SyncService.class);
					lDocsFile.setEntryServer(lDocsFileServer.getEntryServer());
					if (lDocsFileLocal.getLastModified().after(
							lDocsFileServer.getLastModified())) {
						lDocsFile.setDiffType(GDocsFile.DiffType.UPDATE_SERVER);
					} else {
						lDocsFile.setDiffType(GDocsFile.DiffType.EXIST);
					}
				} else {
					LogService.debug("NOT on server - " + lDocsFile.getName(),
							SyncService.class);
					lDocsFile.setDiffType(GDocsFile.DiffType.NOT_EXIST_SERVER);

				}
				lDocsFile.setListGDocs(diff(lDocsFileLocal, lDocsFileServer));
				lDocsFileDiff.add(lDocsFile);
			}
		}
		if (pServerTree != null && pServerTree.getListGDocs() != null) {
			for (GDocsFile lDocsFileServer : pServerTree.getListGDocs()) {
				if (pLocalTree != null
						&& pLocalTree.getListGDocs().contains(lDocsFileServer)) {
					if (!lDocsFileDiff.contains(lDocsFileServer)) {
						lDocsFileDiff.add(lDocsFileServer);
						lDocsFileServer
								.setDiffType(GDocsFile.DiffType.DELETE_SERVER);
						LogService.debug("Local Delete - "
								+ lDocsFileServer.getName(), SyncService.class);
					}
				}
			}
		}
		return lDocsFileDiff;
	}

	/**
	 * 
	 */
	public synchronized void run() {
		GDocsService lGDocsService = getGDocsService();
		doJob(lGDocsService);
		this.setChanged();
		this.notifyObservers(StringUtils.EMPTY);
	}

	/**
	 * @param pGDocsService
	 */
	protected abstract void doJob(GDocsService pGDocsService);

	private static GDocsService getGDocsService() {
		GDocsService lGDocsService = null;
		try {
			lGDocsService = new GDocsService(ConstantesService.getInstance()
					.getValue("conf.username"), ConstantesService.getInstance()
					.getValue("conf.password"), GDocsSync.getInstance());
		} catch (Exception lException) {
			LogService.showError("error.connect", GDocsSync.class, lException);
		}
		return lGDocsService;
	}
}
